package hr.fer.apr.ht41337.lab3;

import hr.fer.apr.ht41337.lab2.funkcije.Funkcija;

import java.util.Random;

public class Jedinka {

	private static Random rnd = new Random();
	
	private int dg;
	private int gg;
	private int n;
	
	private Tocka tocka;
	private int[] b;
	
	public Jedinka(Funkcija f, int n, int dg, int gg)
	{
		this.dg = dg;
		this.gg = gg;
		this.n = n;
		tocka = new Tocka(f.getDimenzija());
		b = new int[f.getDimenzija()];
		for (int i = 0; i < f.getDimenzija(); i++)
		{
			tocka.setX(i, dg + rnd.nextDouble()*(gg-dg));
			b[i] = (int)((tocka.getX(i) - dg ) / (gg - dg) * (Math.pow(2, n) - 1));
		}
	}

	private Jedinka(Tocka tocka, int[] b, int n, int dg, int gg) {
		this.dg = dg;
		this.gg = gg;
		this.b = b;
		this.tocka = tocka;
		this.n = n;
	}



	public Tocka getTocka() {
		return tocka;
	}
	
	public int getB(int i)
	{
		return b[i];
	}

	public Jedinka krizaj(Jedinka druga)
	{
		int A;
		int B;
		int R;
		int[] noviB = new int[tocka.dimenzija];
		Tocka novaTocka = new Tocka(tocka.dimenzija);
		for (int i = 0; i < tocka.dimenzija; i++)
		{
			A = b[i];
			B = druga.getB(i);
			R = rnd.nextInt((int)Math.pow(2,n));
			noviB[i] = (A & B) | (A & R) | (B & R);
			novaTocka.setX(i, (dg + noviB[i] / (Math.pow(2,n) - 1) * (gg - dg)));
		}
		return new Jedinka(novaTocka, noviB, n, dg, gg);
	}
	
	public void mutiraj(double p)
	{
		int maska;
		for (int i = 0; i < tocka.dimenzija; i++)
		{
			maska = 1;
			for (int j = 0; j < n; j++)
			{
				if (rnd.nextDouble() < p)
				{
					b[i] ^= maska;
					tocka.setX(i, (dg + b[i] / (Math.pow(2,n) - 1) * (gg - dg)));
				}
				maska <<= 1;
			}
		}
	}
}
